package org.je.util;

import java.util.ArrayList;
import java.util.List;

/**
 * @author fanyifeng 2012-9-1 上午10:15:10
 */
public class StringUtil
{
	/**
	 * @param s
	 * @return trimmed string
	 */
	public static String trim(String s) {
		if (s == null)
			return null;
		int bg = 0;
		for (; bg < s.length(); ++bg) {
			if (!CharUtil.isBlank(s.charAt(bg)))
				break;
		}
		if (bg >= s.length())
			return "";
		int ed = s.length() - 1;
		for (; ed >= bg; --ed) {
			if (!CharUtil.isBlank(s.charAt(ed)))
				break;
		}
		return s.substring(bg ,ed + 1);
	}

	/**
	 * @param list
	 */
	public static List<String> trimAll(List<String> list) {
		for (int i = 0; i < list.size(); ++i) {
			list.set(i ,trim(list.get(i)));
		}
		return list;
	}

	/**
	 * @param s
	 * @return bool
	 */
	public static boolean isBlankOrNull(String s) {
		return s == null || isBlank(s);
	}

	/**
	 * @param s
	 * @return bool
	 */
	public static boolean isBlank(String s) {
		if (s == null)
			return false;
		for (int i = 0; i < s.length(); ++i) {
			if (!CharUtil.isBlank(s.charAt(i)))
				return false;
		}
		return true;
	}

	/**
	 * @param s1
	 * @param s2
	 * @return bool
	 */
	public static boolean equals(String s1, String s2) {
		return equals(s1 ,s2 ,false);
	}

	/**
	 * @param s1
	 * @param s2
	 * @return bool
	 */
	public static boolean equalsIgnoreCase(String s1, String s2) {
		return equals(s1 ,s2 ,true);
	}

	/**
	 * @param src
	 * @param dest
	 * @param off
	 * @return bool
	 */
	public static boolean match(String src, String dest, int off) {
		if (src == null || dest == null)
			throw new NullPointerException("src:" + src + ",dest:" + dest);
		if (dest.length() == 0 || off + dest.length() > src.length())
			return false;
		return match_not_check(src ,dest ,off);
	}

	/**
	 * 调用这方法前要确保 dest.length > 0
	 * 
	 * @param src
	 * @param dest
	 * @param off
	 * @return bool
	 */
	public static boolean match_not_check(String src, String dest, int off) {
		for (int i = 0; i < dest.length(); ++i) {
			if (src.charAt(off + i) != dest.charAt(i))
				return false;
		}
		return true;
	}

	/**
	 * @param src
	 * @param token
	 * @param replacement
	 * @return str
	 */
	public static String replace(String src, String token, String replacement) {
		if (src == null || token == null || replacement == null || token.length() == 0) {
			throw new IllegalArgumentException("args-cant-null-or-empty");
		}
		int maxIndex = src.length() - token.length();
		StringBuilder bf = new StringBuilder();
		int i = 0;
		for (; i <= maxIndex;) {
			if (match_not_check(src ,token ,i)) {
				bf.append(replacement);
				i += token.length();
			} else {
				bf.append(src.charAt(i));
				++i;
			}
		}
		if (i < src.length()) {
			bf.append(src.substring(i ,src.length()));
		}
		return bf.toString();
	}

	/**
	 * @param src
	 * @param token
	 * @return List[String]
	 */
	public static List<String> split(String src, String token) {
		if (src == null || token == null)
			throw new NullPointerException("src:" + src + ",token:" + token);
		if (token.length() == 0)
			throw new IllegalArgumentException("token-is-empty");

		List<String> list = new ArrayList<String>(8);
		int bg = 0, i = 0, max = src.length() - token.length();

		while( i <= max ) {
			if (match_not_check(src ,token ,i)) {
				if (bg < i)
					list.add(src.substring(bg ,i));
				bg = (i += token.length());
			} else
				++i;
		}
		if (bg < src.length())
			list.add(src.substring(bg));
		return list;
	}

	/**
	 * @param list
	 * @return delete blank null str
	 */
	public static List<String> deleteBlankOrNull(List<String> list) {
		List<String> rst = new ArrayList<String>(list.size());
		for (String s : list) {
			if (StringUtil.isBlankOrNull(s) == false) {
				rst.add(s);
			}
		}
		return rst;
	}

	/**
	 * private methods
	 */

	private static boolean equals(String s1, String s2, boolean ignore) {
		if (s1 == s2)
			return true;
		if (s1 == null || s2 == null)
			return false;
		return ignore ? s1.equalsIgnoreCase(s2) : s1.equals(s2);
	}
}
